package com.situ.mall.recommend;

import com.situ.mall.mapper.ProductDataMapper;
import com.situ.mall.pojo.entity.ProductData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;

@Service
public class ProductSimilarityService {

    @Autowired
    private ProductDataMapper productDataMapper;

    // 获取所有商品的特征向量
    public Map<Integer, double[]> getProductFeatures() {
        // 查询所有商品的数据
        List<ProductData> productDataList = productDataMapper.selectAllProductData();
        // 存储商品特征向量的Map，键为商品ID，值为特征向量数组
        Map<Integer, double[]> productFeatures = new HashMap<>();

        // 遍历每个商品数据，构建特征向量
        for (ProductData product : productDataList) {
            double[] features = new double[4];
            features[0] = product.getSales();
            features[1] = product.getRating();
            features[2] = product.getCollectionCount();
            features[3] = product.getOrderCount();
            productFeatures.put(product.getProductId(), features);
        }
        return productFeatures;
    }

    // 计算余弦相似度
    public double cosineSimilarity(double[] features1, double[] features2) {
        double dotProduct = 0.0;
        double norm1 = 0.0;
        double norm2 = 0.0;

        // 计算特征向量之间的点积及各自的范数平方
        for (int i = 0; i < features1.length; i++) {
            dotProduct += features1[i] * features2[i];
            norm1 += Math.pow(features1[i], 2);
            norm2 += Math.pow(features2[i], 2);
        }

        // 计算余弦相似度并返回
        return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
    }

    // 计算所有商品间的相似度
    public Map<Integer, Map<Integer, Double>> calculateAllSimilarities() {
        // 获取所有商品的特征向量
        Map<Integer, double[]> productFeatures = getProductFeatures();
        // 存储商品间相似度的Map，外层键为商品ID，内层键为相似商品ID，值为相似度
        Map<Integer, Map<Integer, Double>> similarityMatrix = new HashMap<>();

        // 计算所有商品两两之间的相似度
        for (Integer productId1 : productFeatures.keySet()) {
            for (Integer productId2 : productFeatures.keySet()) {
                if (!productId1.equals(productId2)) {
                    // 计算productId1和productId2之间的余弦相似度
                    double similarity = cosineSimilarity(productFeatures.get(productId1), productFeatures.get(productId2));
                    // 将相似度存入相似度矩阵中
                    similarityMatrix.computeIfAbsent(productId1, k -> new HashMap<>()).put(productId2, similarity);
                }
            }
        }
        return similarityMatrix;
    }

}
